#ifndef TEMPCONTROL_H
#define TEMPCONTROL_H

/** ------------------------------------------------------------------------
 * 	Arquivo: tempControl.h
 *	Neste arquivo esta definida a classe para controle de Temperatura.
 *	Um sensor Dallas Temperatura sera utilizado para efetuar as operacoes
 *	de medicao.
 *	Autores:
 *	Luis "Viadao" Ramalho: luispedrojr@gmail.com
 *	Pedro "Pirocudo" Cambier: pedrocambier@gmail.com
 *	Txi "cagueinapia" Felicio: tfelicios@gmail.com
 *	Picocervejaria Flauzue
 *	Criado em: 08/10/2013
 *	Viu como ficou bonitinho meu cabecalho??
 *	Cabecalho no teu cu eh rola!
 * -------------------------------------------------------------------------
 */

/**
 *	Como usar:
 *	Esta eh a classe principal a ser utilizada no sketchbook do Arduino
 *	Da mesma forma que se usa o lcd e outras coisas, antes de qualquer coisa
 *	no seu sketchbook tem que declarar um objeto desta classe.
 *	Ao declarar um objeto novo da classe, esta automaticamente chama o construtor
 *	da classe. Por exemplo:
 *	TempControl luisehviado(PINO, ADRESS);
 *	A parte entre parenteses (PINO, ADRESS) sao os parametros passados pro construtor
 *	O construtor esta definido nesta classe na funcao de mesmo nome da classe:
 *	TempControl(balbalbalbalbla);
 *	Detalhe que tem varios parametros a mais na definicao da funcao, mas eles tem 
 *	valores default: exemplo: resolution = 10, etc. Isto significa que se vc nao
 *	passar nenhum valor para resolution, ele automaticamente usara 10. NO exemplo
 *	acima so passo o Pino e Endereco, o resto usa default.
 *	Na funcao Setup do sketchbook, ao invez de fazer manualmente os setups dos sensores
 *	Simplesmente chama a funcao Setup da TempControl que ja ta tudo embutido la:
 *	luisehviado.Setup();
 *	Esta classe contem um objeto de controle de rampas (_ramps) da classe Ramps (ramps.h)
 *	As principais funcoes desta classe serao chamadas atraves do objeto TempControl mesmo
 *	Por exemplo: adicionar rampas de temperatura, para adicionar, simplesemnte chamar:
 * 	luisehviado.AddRamp(temperatura_inicial, temperatura final, duracao_da_rampa);
 *	Detalhe que estes 3 valores sao do tipo float. Voce pode adicionar ate no maximo
 *	10 Rampas de temperatura, para uma rampa constante, eh so colocar temperatura_inicial
 *	igual a final. As rampas devem ser adicionadas na ordem do tempo.
 *	Agora com tudo inicializado e tendo adicionado as rampas, na funcao loop do sketchbook,
 *	Quando desejar fazer o contrle de temperatura, basta chamar:
 *	luisehviado.Control(tempo_atual);
 *	Esta funcao recebe como parametro o tempo atual em segundos em float. Ela vai verificar
 *	a temperatura de setpoint que deveria atraves das rampas e do tempo atual e vai
 *	retornar 1 caso tenha que aumentar a temperatura, 0 caso contrario e -1 se o tempo passou
 *	do tempo de todas as rampas. Este valor eh retornado em uma variavel do tipo char.
 *	Exemplo: char subir = luisehviado.Control(tempo_atual);
 *	if(subir==1) chama alguem para aumentar a temperatura;
 *	if(subir==0) diminui isso ae!!;
 *	if(subir==-1) para tudo que passou do tempo;
 */

#include <stdint.h>
#include <stddef.h>

#include "ramps.h"

class OneWire;
class DallasTemperature;

// Sensor de temperatura
class TempControl
{
private:
	unsigned int _pin;	// Pino do sensor
	uint8_t *_address;	// Endereco do sensor
	float *_tempsVector;// Vetor contendo temperaturas lidas
	float _sumTemp;		// Temperatura media para corrigir picos
	float _maxTemp;         // Temperatura maxima dentro do vetor
	float _minTemp;         // Temperatura minima dentro do vetor
	unsigned int _resolution;	// Resolucao da leitura
	unsigned int _vectorSize;	// Tamanho do vetor de temperaturas lidas
	unsigned int _vectorPos;	// Posicao do proximo valor a ser inserido no vetor de temps
	bool _firstTemp;		// Indicador de primeira leitura
	Ramps _ramps;   // Objeto de controle das rampas de temperatura
	OneWire *_sensor;		// Ponteiro para sensor
	DallasTemperature *_dallas;	// Ponteiro pra Dallas

private:
	// Retorna a temperatura lida e calcula media, maximo e minimo
	float _temperatureGet(unsigned int buffsize = 256);
public:
/**
 * Constutores
 */

	// Costrutor, recebe pin, endereco, resolucao e tamanho do vetor
	TempControl(unsigned int pin, uint8_t *address = NULL, unsigned int resolution = 10, unsigned int vectorsize = 10, float hister = 0.1);

	// Destrutor
	~TempControl();

	public:
/**
 * Modificadores
 */

	// Faz o setup do sensor
	void Setup();
	
	// Define ou redefine o endereco do sensor
	bool addressSet (uint8_t *address);

	// Define ou redefine a resolucao do sensor
	bool resolutionSet (unsigned int resolution);
	
	// Adiciona rampa de temperatura
	bool AddRamp(float tempi, float tempf, float duration);

	// Inicializa os tempos das rampas de temperatura
	void Start(float time) {_ramps.Start(time);}

	// Inicializa os tempos das rampas de temperatura
	void Start() {_ramps.Start();}
	// Atualiza o tempo nas rampas e verifica temperatura
	// Retorna true para aumentar e false para manter temperatura
	// Funcao principal do controle de temperatura, a partir dela 
	// serao chamadas funcoes para controlar o dispositivo de aquecimento
	char Control(float time = -1.0);

/**
 * Acessores
 */
	// Retorna media movel
	float avgGet()
	{
		return _sumTemp/_vectorSize;
	}
		
	// Retorna maximo
	float maxGet()
	{
		return _maxTemp;
	}
	
	//Retorna minimo
	float minGet()
	{
		return _minTemp;
	}
	
	// Funcao de debug, para testar
	// Imprime as temperaturas no Serial
	void SerialPrint();
};

#endif //TEMPCONTROL_H
